<?php if ( ! defined('BASEPATH')) exit('No direct script access allowed'); 

/**
 *
 * 权限控制类
 * auther xiaomai
 */
class Auth
{
	private $_CI;
	private $node;  //节点

	 /**
     * 构造函数
     * @access public
     * @return void
     */
    public function __construct()
    {
        /** 获取CI句柄 */
		$this->_CI = & get_instance();
		$this->_CI->load->model('mauth');
		$this->getNode();
    }
	
	//获取url节点
	protected function getNode(){
		$CONTROLLER_NAME =  $this->_CI->router->fetch_class();
		$ACTION_NAME =  $this->_CI->router->fetch_method();    // 当前使用方法
		$this->node = strtolower($CONTROLLER_NAME.'/'.$ACTION_NAME);
	}

	  /**
      * 检查权限
      * @param name string|array  需要验证的规则列表,支持逗号分隔的权限规则或索引数组
      * @param uid  int           认证用户的id
      * @param string mode        执行check的模式
      * @param relation string    如果为 'or' 表示满足任一条规则即通过验证;如果为 'and'则表示需满足所有规则才能通过验证
      * @return boolean           通过验证返回true;失败返回false
     */
    public function check($uid, $type=1, $mode='url', $relation='or') {
			$authList = $this->getAuthList($uid,$type); //获取用户需要验证的所有有效规则列表
			
			$name = 'admin/'.$this->node;   //这里可以根据分组做
			//这一步理论上可以省了（参考TP的）
			if (is_string($name)) {
				$name = strtolower($name);
				if (strpos($name, ',') !== false) {
					$name = explode(',', $name);
				} else {
					$name = array($name);
				}
			}

			$list = array(); //保存验证通过的规则名
			if ($mode=='url') {
				$REQUEST = unserialize( strtolower(serialize($_REQUEST)) );
			}
			
			foreach ( $authList as $auth ) {
				$query = preg_replace('/^.+\?/U','',$auth);
				if ($mode=='url' && $query!=$auth ) {
					parse_str($query,$param); //解析规则中的param
					$intersect = array_intersect_assoc($REQUEST,$param);
					$auth = preg_replace('/\?.*$/U','',$auth);
					if ( in_array($auth,$name) && $intersect==$param ) {  //如果节点相符且url参数满足
						$list[] = $auth ;
					}
				}else if (in_array($auth , $name)){
					$list[] = $auth ;
				}
			}

			if ($relation == 'or' and !empty($list)) {
				return true;
			}

			$diff = array_diff($name, $list);	//比较两个数组的键值，并返回差集：
			if ($relation == 'and' and empty($diff)) {
				return true;
			}
			return false;
    }


     /**
     * 根据用户id获取用户组,返回值为数组
     * @param  uid int     用户id
     * @return array       用户所属的用户组 array(
     * array('uid'=>'用户id','group_id'=>'用户组id','title'=>'用户组名称','rules'=>'用户组拥有的规则id,多个,号隔开'),
     * Array ( [0] => Array ( [uid] => 2 [group_id] => 3 [title] => 运营专员 [rules] => 1,2,3,4,23,24 ) )
     */
     protected function getGroups($uid) {
        static $groups = array();
        if (isset($groups[$uid]))
            return $groups[$uid];
			
        $user_groups = $this->_CI->mauth->getGroups($uid);
		$groups[$uid]=$user_groups?:array();
		return $groups[$uid];
    }


     /**
     * 获得权限列表
     * @param integer $uid  用户id
     * @param integer $type 
	 * Array ( [0] => admin/index/index [1] => admin/index/test [2] => admin/user/index [3] => admin/game/index [4] => admin/game/game_list [5] => admin/game/game_add )
	 * protected
     */
     protected function getAuthList($uid,$type=1) {  //应该通过groupid好点
		static $_authList = array(); //保存用户验证通过的权限列表
	    //读取用户所属用户组
		
        $groups = $this->getGroups($uid);
        $ids = array();//保存用户所属用户组设置的所有权限规则id
        foreach ($groups as $g) {
            $ids = array_merge($ids, explode(',', trim($g['rules'], ',')));
        }
        $ids = array_unique($ids); //Array ( [0] => 1 [1] => 2 [2] => 3 [3] => 4 [4] => 23 [5] => 24 )
		
        if (empty($ids)) {
            $_authList[$uid] = array();
            return array();
        }
	
        $map=array(
          
        );
		
		$rules = $this->_CI->mauth->getAuthList($map,$ids);

		//循环规则，判断结果。
        $authList = array();   //
        foreach ($rules as $rule) {
            if (!empty($rule['condition'])) { //根据condition进行验证
                $user = $this->getUserInfo($uid);//获取用户信息,一维数组

                $command = preg_replace('/\{(\w*?)\}/', '$user[\'\\1\']', $rule['condition']);
                //dump($command);//debug
                @(eval('$condition=(' . $command . ');'));
                if ($condition) {
                    $authList[] = strtolower($rule['name']);
                }
            } else {
                //只要存在就记录
                $authList[] = strtolower($rule['name']);
            }
        }
		
		//只要存在就记录
        $authList[] = strtolower($rule['name']);
		//这一步，为了提高性能，可以用缓存服务这里暂时不用
		return array_unique($authList);

    }


     /**
     * 获得用户资料,根据自己的情况读取数据库
	 *
     */
    protected function getUserInfo($uid) {
        static $userinfo=array();
        if(!isset($userinfo[$uid])){
             $userinfo[$uid]=M()->where(array('uid'=>$uid))->table($this->_config['AUTH_USER'])->find();
        }
        return $userinfo[$uid];
    }
	
}

/* End of file AuthBoss.php */
/* Location: ./application/libraries/AuthBoss.php */